How to Use Inactive

Itai Seggev

Wolfram Research, Inc.

Our cast of characters

Familiar:

Hold

HoldComplete

HoldForm

HoldPattern, Evaluate, Unevaluated

New:

Inactive

Inactivate

Activate

I come neither to praise nor bury Caesar

Traditional idioms allow—and require—complete control over evaluation

Examples

Grid[Table[{HoldForm[Sin[k π/6]]==Sin[k π/6],HoldForm[Cos[k π/6]]==Cos[k π/6]},{k,0,3}], Alignment->Left]

int = Hold@Integrate[Gamma[x],x];
D[int,x]

A taste of Inactive

Examples

Grid[Table[{Inactive[Sin][k π/6]==Sin[k π/6],Inactive[Cos][k π/6]==Cos[k π/6]},{k,0,3}],Alignment->Left]

int = Inactivate[Integrate[Gamma[x],x], Integrate]
D[int,x]

Inactive and friends

Inactive[f][args] — the inactive from of f

Inactivate[expr] — replaces every head h with Inactive[h]

Inactivate[expr, patt] — replace only symbols matching patt

Activate[expr] — replaces every Inactive[h]with h

Activate[expr, patt] — replace only if h matches patt

Basic Examples

Just sine I

Inactivate[Sin[Pi]]

%//InputForm

%//Activate

Just sine II

Perhaps a bit of a surprise?

Inactivate[Sin[Pi/4]]

%//Activate

Being more explicit:

Inactivate[Sin[Pi/4], Sin]

Basic Examples—continued

Sine and cosine

Do a computation one step at a time

expr =Inactivate[Cos[(π/3)]+Sin[(π/6)], Sin | Cos]

Activate[expr,Sin]

Activate[%,Cos]

Or perhaps in the other order

Activate[expr,Cos]

Activate[%,Sin]

Inactive styling

Grey styling in StandardForm:

Inactivate[{2+2,f[x], Cosh[y], Div[g,x], Sum[f[k], {k,min, max}]}]

But not TraditionalForm

%//TraditionalForm

Mathematical identities I

Fourier transform

Clear[f,t,ω]
Inactivate[FourierTransform[f,t,ω]]

D knows how to deal with FourierTransform

der=D[%,ω]

Activate for a particular function:

f=Exp[-t^2];
Activate[der]

Curl grad

A famous identity

Clear[grad, t,f, x,y,z]
grad = Inactivate[Grad[t, {x,y,z}]]

t = f[x,y,z];
Curl[grad,{x,y,z}]

A lesser known variant:

t = {(Subscript[f, 1])[x,y,z],(Subscript[f, 2])[x,y,z],(Subscript[f, 3])[x,y,z]};
Curl[grad,{x,y,z}]

A non-identity:

t = Array[(Subscript[f, ##])[x,y,z]&, {3,3}];
Curl[grad,{x,y,z}]

Mathematical identities II

Feynman’s trick for ∫x (e^x)dx

Clear[x,a]
expr = Inactivate[D[Integrate[(E^(a x)), x],a], Integrate | D]

First differentiate at a==1:

Activate[expr, D]
lhs=% /. a->1

Then, do the integration first followed by differentiation:

Activate[expr, Integrate]
Activate[%, D]
rhs=% /. a->1

We get a result:

lhs == rhs

Verify the result:

Activate[%]//Simplify

Working with PDEs

Laplace’s equation

Solution for the three-dimensional Laplace equation in inactive integral form:

Clear[v,f,x,y,z]
V[f_,x_,y_,z_]:=Inactive[Integrate][f[z + I*x*Cos[u] + I*y*Sin[u], u], {u, -Pi, Pi}]

Obtain a particular solution by specifying the function f:

f[a_,b_]:=2a^5+b^4

V[f,x,y,z]

sol=Activate[%]//Simplify

Visualize the solution:

Row[Table[Plot3D[sol/.{z-> j},{x,-3,3},{y,-3,3},Ticks->{Automatic,Automatic,None}],{j,-2,2}]]

Verify the solution:

Laplacian[sol,{x,y,z}]//Simplify

Maxwell’s equations

Maxwell's equations in natural Lorentz-Heaviside units:

Clear[x,y,z,ρ,t]
Inactivate[{gaussE=Div[ℰ[x,y,z,t],{x,y,z}]==ρ[x,y,z,t],gaussB=Div[ℬ[x,y,z,t],{x,y,z}]==0,faraday=Curl[ℰ[x,y,z,t],{x,y,z}]==-D[ℬ[x,y,z,t],t],ampere=Curl[ℬ[x,y,z,t],{x,y,z}]== j[x,y,z,t]+D[ℰ[x,y,z,t],t]},Div|Curl|D];
%//TableForm//TraditionalForm

Take the curl of Ampere's Law in vacuum (j==0 and ρ==0):

Inactive[Curl][#, {x,y,z}]& /@ ampere /. j->(0&)

Interchange order of differentiation:

% /. Inactivate[Curl[D[v_,t_],x_] :> D[Curl[v,x],t]]

Substitute in Faraday's law:

% /. Solve[faraday,Inactive[Curl][ℰ[x,y,z,t],{x,y,z}]][[1]]

Activate the equation, resulting in the wave equation for the magnetic field:

wave=Activate[%]

Verify plane-wave solutions of the equation:

wave/.ℬ->(A Exp[{kx,ky,kz}.{#1,#2,#3}-I(Sqrt[kx^2+ky^2+kz^2])#4]&)//Simplify

Some technical issues

Inactivate is Idempotent

Inactivate[Sin[Pi]]//InputForm

Inactive[Sin][Pi]//Inactivate

%//InputForm

Inactivate is HoldFirst

Clear[a,x];
a = Sin[x]

Wrong:

Inactivate[a]

Right:

Inactivate @@ {a}

Inactivate[a//Evaluate]

With[{a=a},Inactivate[a]]

Note, so is Inactive:

Inactive//Attributes

A few exceptions

Some heads are never inactivated (notably List and patterns):

Inactivate[{ Blank[], Alternatives[Sin[x], Cos[x], Tan[x]]}]

%//InputForm

The default exclusions are stored in the variable Developer`$InactivateExclusions:

Developer`$InactivateExclusions

You can either Block or assign a custom value to this variable:

Developer`$InactivateExclusions={}

Inactivate[{ Blank[], Alternatives[Sin[x], Cos[x], Tan[x]]}]

Unsetting it will restore the default value

Developer`$InactivateExclusions=.
Developer`$InactivateExclusions

IgnoringInactive

A new pattern object which allows the activate and inactive forms

Log[x] /. (h: IgnoringInactive[Log])[x_] :> (Print["h matched: ", h] ; x)

Inactive[Log][x] /. (h: IgnoringInactive[Log])[x_] :> (Print["h matched: ", h] ; x)

It doesn’t have to wrap just the head:

Log[x] /. IgnoringInactive[Log[x_]] :>x

Inactive[Log][x] /. IgnoringInactive[Log[x_]] :>x

Final Thoughts

Inactive is finer than Hold et alia

Well suited for mathematical applications

But sufficient control for others

My fellow Inactive developers:

Devendra Kapadia    Rob Knapp      Roger Germundsson

Questions?